package co.fitstart.mobile.service.impl;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.demo2do.core.persistence.GenericDaoSupport;

import co.fitstart.entity.course.round.CourseRound;
import co.fitstart.entity.course.round.OnlineRoundGroupStatus;
import co.fitstart.entity.course.round.RoundStatus;
import co.fitstart.entity.order.Order;
import co.fitstart.entity.principal.Principal;
import co.fitstart.entity.user.Student;
import co.fitstart.entity.user.User;
import co.fitstart.entity.user.bwh.BwhRecord;
import co.fitstart.mobile.dao.support.ScheduleDaoSupport;
import co.fitstart.mobile.dao.support.StudentDaoSupport;
import co.fitstart.mobile.service.CourseRoundService;

/**
 * 
 * @author mohanlan
 *
 */
@Service("courseRoundService")
public class CourseRoundServiceImpl implements CourseRoundService {
    
    @Autowired
    private GenericDaoSupport genericDaoSupport;
    
    @Autowired
    private ScheduleDaoSupport scheduleDaoSupport;
    
    @Autowired
    private StudentDaoSupport studentDaoSupport;
    
    /* (non-Javadoc)
     * @see co.fitstart.mobile.service.CourseRoundService#listCourseRound(co.fitstart.entity.user.Student, boolean)
     */
    @SuppressWarnings("unchecked")
    public List<CourseRound> listCourseRound(Student student, boolean finish) {
        
        String sentence = "FROM CourseRound courseRound WHERE courseRound.student = :student";
        
        sentence += finish ? " AND courseStatus = :courseStatus" : " AND courseStatus not in (:courseStatus)";
        
        Map<String, Object> parameters = new HashMap<String, Object>(4);
        parameters.put("student", student);
        
        if(finish) {
            parameters.put("courseStatus", RoundStatus.FINISH);
        } else {
            List<RoundStatus> roundStatus = Arrays.asList(new RoundStatus[]{RoundStatus.FINISH, RoundStatus.CANCEL});
            parameters.put("courseStatus", roundStatus);
        }
        
        sentence = sentence + " ORDER BY courseRound.createTime DESC";
        
        return genericDaoSupport.searchForList(sentence, parameters);
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CourseRoundService#listCourseRoundIds(java.lang.String, java.lang.String, boolean)
     */
    public CourseRound loadCourseRound(User user, String code, String groupName, boolean grouped) {
        Map<String, Object> parameters = new HashMap<String, Object>();
        String sentence = "";
        
        if(!grouped && StringUtils.isBlank(groupName)) {
            sentence = "FROM CourseRound WHERE disabled = false AND code = :code AND student.user = :user";
        } else if(grouped && StringUtils.isNoneBlank(groupName)) {
            sentence = sentence + "SELECT group.courseRound FROM CourseRoundGroup group WHERE group.disabled = false AND group.courseRoundCode = :code AND group.courseRound.student.user = :user AND group.name = :name";
            parameters.put("name", groupName);
        } else if (grouped && StringUtils.isBlank(groupName)) {
            sentence = "FROM CourseRound WHERE disabled = false AND code = :code AND student.user = :user AND onlineRoundAttr.onlineRoundGroupStatus in (:status)";
            parameters.put("status", new OnlineRoundGroupStatus[]{OnlineRoundGroupStatus.DISALLOW_GROUP, OnlineRoundGroupStatus.UNGROUPED});
        }
        
        parameters.put("user", user);
        parameters.put("code", code);
        
        return genericDaoSupport.searchForObject(sentence, parameters, CourseRound.class);
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CourseRoundService#loadCourseRound(java.lang.Long)
     */
    public CourseRound loadCourseRound(Long courseRoundId) {
        return genericDaoSupport.load(CourseRound.class, courseRoundId);
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CourseRoundService#loadCourseRound(co.fitstart.entity.order.Order)
     */
    public CourseRound loadCourseRound(Order order) {
        return genericDaoSupport.searchForObject("FROM CourseRound WHERE disabled = false AND order = :order", "order", order, CourseRound.class);
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CourseRoundService#loadCoach(java.lang.Long)
     */
    public Principal loadCoach(Long coachId) {
        return genericDaoSupport.load(Principal.class, coachId);
    }
    
    /* (non-Javadoc)
     * @see co.fitstart.mobile.service.CourseRoundService#needTargetData(co.fitstart.entity.user.Student, co.fitstart.entity.course.round.CourseRound)
     */
    public boolean needTargetData(Student student, CourseRound courseRound) {
        
        int schedules = scheduleDaoSupport.count(student, courseRound);
        int targets = studentDaoSupport.countStudentTargetData(student, courseRound);
        
        if ((schedules % 12 == 0) && (schedules / 12 >= targets)) {
            return true;
        } else {
            return false;
        } 
        
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CourseRoundService#editRoundZipName(co.fitstart.entity.user.User)
     */
    @SuppressWarnings("unchecked")
    public void editRoundZipName(User user) {
        // list user's online round
        String sentence = "FROM CourseRound WHERE disabled = false AND student.user = :user AND courseType = 0 AND onlineRoundAttr.zipName IS NOT NULL";
        List<CourseRound> courseRounds = genericDaoSupport.searchForList(sentence, "user", user);
        
        for (CourseRound courseRound : courseRounds) {
            genericDaoSupport.update(courseRound.editZipName(user.getWechat().getCode()));
        }
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CourseRoundService#fullInTarget(co.fitstart.entity.course.round.CourseRound, boolean)
     */
    public void fullInTarget(CourseRound courseRound, boolean fullIn) {
        genericDaoSupport.update(courseRound.fullInTarget(fullIn));
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CourseRoundService#createbwhRecord(co.fitstart.entity.user.bwh.BwhRecord, co.fitstart.entity.course.round.CourseRound)
     */
    public void createbwhRecord(BwhRecord bwhRecord, CourseRound courseRound) {
        genericDaoSupport.save(bwhRecord.initilization(courseRound));
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CourseRoundService#list(java.util.List)
     */
    @SuppressWarnings("unchecked")
    public List<CourseRound> list(List<String> couponIds, boolean finish) {
        List<Order> orders = genericDaoSupport.searchForList("SELECT order FROM OrderAttribute WHERE name = 'couponId' AND value IN ( :couponIds)", "couponIds", couponIds);

        if(orders == null || orders.size() == 0) {
            return null;
        } else {
            String sentence = "FROM CourseRound WHERE order IN ( :orders)";
            
            sentence += finish ? " AND courseStatus = :courseStatus" : " AND courseStatus not in (:courseStatus)";
            
            Map<String, Object> parameters = new HashMap<String, Object>(4);
            parameters.put("orders", orders);
            
            if(finish) {
                parameters.put("courseStatus", RoundStatus.FINISH);
            } else {
                List<RoundStatus> roundStatus = Arrays.asList(new RoundStatus[]{RoundStatus.FINISH, RoundStatus.CANCEL});
                parameters.put("courseStatus", roundStatus);
            }
            
            sentence = sentence + " ORDER BY createTime DESC";
            
            return genericDaoSupport.searchForList(sentence, parameters);
        }
    }
}
